package com.wdb007.venus.web.api.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wdb007.venus.svc.biz.utils.MD5Util;
import com.wdb007.venus.svc.facade.constant.RspCodeEnum;
import com.wdb007.venus.svc.facade.exception.BizException;
import com.wdb007.venus.svc.facade.exception.SysException;
import com.wdb007.venus.web.api.Jsonable;
import com.wdb007.venus.web.api.model.BaseResponse;

public class CheckSignFilter implements Filter {

	private static final Logger logger = LoggerFactory.getLogger(CheckSignFilter.class);
	
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		//验签 sign / ts / ver
		String sign = httpRequest.getHeader("sign");
		String ts = httpRequest.getHeader("ts");//timestamp
		String ver = httpRequest.getHeader("ver");//version
		String source = httpRequest.getHeader("source");//version
		String token = httpRequest.getHeader("token");//token/key
		String appId = httpRequest.getHeader("appId");//appId
		String data = httpRequest.getHeader("data");
		if(ObjectUtils.isEmpty(data)) data = "";
		if(ObjectUtils.isEmpty(appId)) appId = "";
		//获取parameter参数
		try {
			Enumeration<String> names = request.getParameterNames();
			String param = "";//所有参数加密
			while(names.hasMoreElements()){
				String key = names.nextElement();
				param += (key + "=" + request.getParameter(key) + "&");
			}
			if(param != null && param.length() > 0) {
				param = param.substring(0, param.length()-1);
			}
			String url = httpRequest.getRequestURL().append("?") + param;
			logger.info("checksign token:{}, ts:{}, ver:{}, source:{}, appId:{}, url:{}, data:{} ",	token, ts, ver, source, appId, url, data);
			if("wx_app".equals(source) && ver != null && "1.2.4".compareTo(ver) < 0){
				//时间戳判断
				if(Math.abs(new Date().getTime() - Long.valueOf(ts)) > 10000*60*15) {
					logger.info("时间戳对比不上");
				}
				String sourceData = token + appId + ts + url.replace("http://", "https://") + data;
				String signature = MD5Util.MD5Encode(sourceData, "UTF-8");
				
				logger.info("request sourceData: [{}] , sign: [{}],fix:[{}]" , sourceData, signature, signature.equals(sign));
				if(! signature.equalsIgnoreCase(sign)) {//验签不正确
//					throw new RRException(RspCodeEnum.SIGN_IS_ERROR);
					logger.info("验证签名不正确");
				}
			}
			chain.doFilter(request, response);
		}catch(Exception e){
			logger.error(e.getMessage(), e);
			BaseResponse<Jsonable> res = new BaseResponse();
			res.setResult(0);
			if(e instanceof BizException) {
				BizException bizRuntimeException = (BizException) e;
				res.setCode(bizRuntimeException.getErrorCode());
				res.setMessage(bizRuntimeException.getErrorMsg());
			}else if(e instanceof SysException) {
				SysException sysRuntimeException = (SysException) e;
				res.setCode(sysRuntimeException.getErrorCode());
				res.setMessage(sysRuntimeException.getErrorMsg());
			}else {
				res.setCode(1010080099);
				res.setMessage("系统异常，请联系管理员");
			}
//			responseOutWithJson((HttpServletResponse)response, res);
		}
	}

	private void responseOutWithJson(HttpServletResponse httpResponse, Object response) {
		JSONObject jsonObject = (JSONObject) JSON.toJSON(response);
		httpResponse.setCharacterEncoding("UTF-8");
		httpResponse.setContentType("application/json; charset=utf-8");  
		PrintWriter out = null;  
	    try {  
	        out = httpResponse.getWriter();  
	        out.append(jsonObject.toString());  
	        logger.debug(jsonObject.toString());  
	        out.flush();
	    } catch (IOException e) {  
	        e.printStackTrace();  
	    } finally {  
	        if (out != null) {  
	        }  
	    }  
	}
	
	@Override
	public void init(FilterConfig config) throws ServletException {
	}

}
